package com.mender.data.service.impl;

import com.mender.api.client.TradeClient;
import com.mender.api.client.UserClient;
import com.mender.common.result.Result;
import com.mender.data.domain.vo.BusinessDataVO;
import com.mender.data.domain.vo.SalesTop10ReportVO;
import com.mender.data.domain.vo.TurnoverReportVO;
import com.mender.data.service.ReportService;
import com.mender.data.service.WorkspaceService;
import com.mender.domain.dto.GoodsSalesDTO;
import com.mender.domain.po.Orders;
import com.mender.domain.vo.OrderReportVO;
import com.mender.domain.vo.UserReportVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ReportServiceImpl implements ReportService {

    @Autowired
    private TradeClient tradeClient;

    @Autowired
    private UserClient userClient;

    @Autowired
    private WorkspaceService workspaceService;

    /**
     * 统计指定某个时间段内的营业额统计
     * @param begin
     * @param end
     * @return
     */
    @Override
    public TurnoverReportVO getTurnoverStatistics(LocalDate begin, LocalDate end) {
        // 构造完整时间段（LocalDate -> LocalDateTime）
        LocalDateTime beginTime = begin.atStartOfDay();              // 00:00:00
        LocalDateTime endTime = end.atTime(LocalTime.MAX);           // 23:59:59.999...

        // 构造日期列表
        List<LocalDate> dateList = new ArrayList<>();
        LocalDate currentDate = begin;
        while (!currentDate.isAfter(end)) {
            dateList.add(currentDate);
            currentDate = currentDate.plusDays(1);
        }

        // 查询所有已完成订单数据（一次性查出范围内所有订单）
        Result<List<Orders>> RordersList = tradeClient.getCompletedOrdersByTime(beginTime, endTime, Orders.COMPLETED);
        List<Orders> ordersList = RordersList.getData();

        // 按天聚合营业额
        Map<LocalDate, Double> turnoverMap = new HashMap<>();
        for (Orders order : ordersList) {
            LocalDate date = order.getOrderTime().toLocalDate();  // 按日期聚合
            turnoverMap.put(date, turnoverMap.getOrDefault(date, 0.0) + order.getAmount().doubleValue());
        }

        // 构造结果字符串列表
        List<String> dateStrList = new ArrayList<>();
        List<String> turnoverStrList = new ArrayList<>();
        for (LocalDate date : dateList) {
            dateStrList.add(date.toString());  // yyyy-MM-dd
            turnoverStrList.add(String.valueOf(turnoverMap.getOrDefault(date, 0.0)));
        }

        // 封装 VO 返回
        return TurnoverReportVO.builder()
                .dateList(StringUtils.join(dateStrList, ","))          // "2025-07-22,2025-07-23,..."
                .turnoverList(StringUtils.join(turnoverStrList, ","))  // "120.0,200.0,..."
                .build();
    }

    /**
     * 用户数据统计
     * @param begin
     * @param end
     * @return
     *
     * TODO 优化:一次性查出所有数据,使用java进行业务处理
     */
    @Override
    public UserReportVO getUserStatistics(LocalDate begin, LocalDate end) {
//        存放begin到end每天的日期
        List<LocalDate> dateList = new ArrayList<>();
        while (!begin.isAfter(end)) {
            dateList.add(begin);
            begin = begin.plusDays(1);
        }

//        每天新增的用户数
        List<Integer> newUserList = new ArrayList<>();
//        每天的用户总量
        List<Integer> totalUserList = new ArrayList<>();

        for (LocalDate date : dateList) {
            LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);
            Map map = new HashMap<>();
            map.put("end", endTime);
//            总用户数
            Result RcountUserTotal = userClient.countNewUserByMap(map);
            Integer countUserTotal = (Integer) RcountUserTotal.getData();
            map.put("begin", beginTime);
//            新增的用户数
            Result RnewUser = userClient.countNewUserByMap(map);
            Integer newUser = (Integer) RnewUser.getData();
            totalUserList.add(countUserTotal);
            newUserList.add(newUser);
        }

        return UserReportVO.builder()
                .dateList(StringUtils.join(dateList, ","))
                .newUserList(StringUtils.join(newUserList, ","))
                .totalUserList(StringUtils.join(totalUserList, ","))
                .build();
    }

    /**
     * 订单数据统计
     * @param begin
     * @param end
     * @return
     */
    @Override
    public OrderReportVO getOrdersStatistics(LocalDate begin, LocalDate end) {
        LocalDateTime beginTime = begin.atStartOfDay();
        LocalDateTime endTime = end.atTime(LocalTime.MAX);
        //        存放begin到end每天的日期
        List<LocalDate> dateList = new ArrayList<>();
        while (!begin.isAfter(end)) {
            dateList.add(begin);
            begin = begin.plusDays(1);
        }
//        一次性查询所有订单数据（包含所有状态）
        Result<List<Orders>> RordersList = tradeClient.getCompletedOrdersByTime(beginTime, endTime,null);
        List<Orders> ordersList = RordersList.getData();

        List<String> orderCountList = new ArrayList<>();
        List<String> validOrderCountList = new ArrayList<>();
        int totalOrderCount = 0;
        int validOrderCount = 0;
        for (LocalDate date  : dateList) {
            LocalDateTime dayStart = date.atStartOfDay();
            LocalDateTime dayEnd = date.atTime(LocalTime.MAX);

            // 统计每日订单数
            long dailyOrderCount = ordersList.stream()
                    .filter(o -> !o.getOrderTime().isBefore(dayStart) && !o.getOrderTime().isAfter(dayEnd))
                    .count();

            // 统计每日有效订单数（已完成）
            long dailyValidCount = ordersList.stream()
                    .filter(o -> o.getStatus().equals(Orders.COMPLETED))
                    .filter(o -> !o.getOrderTime().isBefore(dayStart) && !o.getOrderTime().isAfter(dayEnd))
                    .count();

            orderCountList.add(String.valueOf(dailyOrderCount));
            validOrderCountList.add(String.valueOf(dailyValidCount));

            totalOrderCount += dailyOrderCount;
            validOrderCount += dailyValidCount;
        }
//        订单完成率
        double orderCompletionRate = totalOrderCount > 0 ?
                (validOrderCount * 1.0 / totalOrderCount) : 0.0;

        return OrderReportVO.builder()
                .dateList(dateList.stream().map(LocalDate::toString).collect(Collectors.joining(",")))
                .orderCountList(String.join(",", orderCountList))
                .validOrderCountList(String.join(",", validOrderCountList))
                .totalOrderCount(totalOrderCount)
                .validOrderCount(validOrderCount)
                .orderCompletionRate(orderCompletionRate)
                .build();
    }


    /**
     * 查询销量排名top10
     * @param begin
     * @param end
     * @return
     */
    @Override
    public SalesTop10ReportVO getTop10(LocalDate begin, LocalDate end) {
        LocalDateTime beginTime = begin.atStartOfDay();
        LocalDateTime endTime = end.atTime(LocalTime.MAX);

//      根据指定时间查询符合条件的菜品
        Result<List<GoodsSalesDTO>> RgoodsSalesDTOList = tradeClient.getOrderDetailTop10(beginTime, endTime);
        List<GoodsSalesDTO> goodsSalesDTOList = RgoodsSalesDTOList.getData();

        String nameList = goodsSalesDTOList.stream().map(GoodsSalesDTO::getName).collect(Collectors.joining(","));
        String numberList = goodsSalesDTOList.stream().map(GoodsSalesDTO::getNumber).map(String::valueOf).collect(Collectors.joining(","));

        return SalesTop10ReportVO.builder()
                .nameList(nameList)
                .numberList(numberList)
                .build();
    }

    /**
     * 导出运营数据报表
     * @param response
     */
    @Override
    public void export(HttpServletResponse response) {
//        查询数据库获取营业数据
        LocalDate localDateBegin = LocalDate.now().minusDays(30);
        LocalDate localDateEnd = LocalDate.now().minusDays(1);
        LocalDateTime beginTime = localDateBegin.atStartOfDay();
        LocalDateTime endTime = localDateEnd.atTime(LocalTime.MAX);
//        查询出概览数据
        BusinessDataVO businessData = workspaceService.getBusinessData(beginTime, endTime);
        InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("template/Operation_data_report_template.xlsx");
        //        将数据写入excel文件
        try {
//        基于运营数据报表模板文件 创建excel文件
            XSSFWorkbook excel = new XSSFWorkbook(resourceAsStream);
//            填充数据
//            获取表格sheet标签页
            XSSFSheet sheetAt = excel.getSheetAt(0);
//            在第二列第二行填充时间
            sheetAt.getRow(1).getCell(1).setCellValue("时间:"+localDateBegin+"-"+localDateEnd);
//            获得第四行,填充     营业额 ,订单完成率 ,新增用户数
            XSSFRow row3 = sheetAt.getRow(3);
            row3.getCell(2).setCellValue(businessData.getTurnover());
            row3.getCell(4).setCellValue(businessData.getOrderCompletionRate());
            row3.getCell(6).setCellValue(businessData.getNewUsers());
            //            获得第五行,填充     有效订单数 ,平均客单价
            XSSFRow row4 = sheetAt.getRow(4);
            row4.getCell(2).setCellValue(businessData.getValidOrderCount());
            row4.getCell(4).setCellValue(businessData.getUnitPrice());

//            填充每日明细数据
            for (int i = 0; i < 30; i++) {
                LocalDate date = localDateBegin.plusDays(i);
//                查询某一天的营业数据
                BusinessDataVO businessData1 = workspaceService.getBusinessData(LocalDateTime.of(date, LocalTime.MIN), LocalDateTime.of(date, LocalTime.MAX));
//                从第八行开始
                XSSFRow rows = sheetAt.getRow(i + 7);
                rows.getCell(1).setCellValue(date.toString());
                rows.getCell(2).setCellValue(businessData1.getTurnover());
                rows.getCell(3).setCellValue(businessData1.getValidOrderCount());
                rows.getCell(4).setCellValue(businessData1.getOrderCompletionRate());
                rows.getCell(5).setCellValue(businessData1.getUnitPrice());
                rows.getCell(6).setCellValue(businessData1.getNewUsers());

            }

//        将excel文件写入到响应中
            ServletOutputStream outputStream = response.getOutputStream();
            excel.write(outputStream);
//            关闭资源
            outputStream.close();
            excel.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

}
